home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 018 / amigadisplay / intuit.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  14KB  |  376 lines

  1. /*********************************************************************\
  2. * This file has Intuition-related stuff: menus, fonts, etc (intuit.c) *
  3. \*********************************************************************/
  4.  
  5. #include <exec/types.h>
  6. #include <exec/exec.h>
  7. #include <stdio.h>
  8. #include <libraries/diskfont.h>
  9. #include <intuition/intuitionbase.h>
  10. #include <intuition/intuition.h>
  11.  
  12. /* Library pointers imported from main.c */
  13. extern struct IntuitionBase *IntuitionBase;
  14. extern struct GfxBase       *GfxBase;
  15. extern struct DiskfontBase  *DiskfontBase;
  16.  
  17. /*
  18.  * Initialise an IntuiText structure
  19.  */
  20.  
  21. /* constants for pen colors */
  22. #define FORE0  (0 << 2)
  23. #define FORE1  (1 << 2)
  24. #define FORE2  (2 << 2)
  25. #define FORE3  (3 << 2)
  26. #define BACK0  0
  27. #define BACK1  1
  28. #define BACK2  2
  29. #define BACK3  3
  30.  
  31. static InitText(intui, text, pens, left, top) struct IntuiText *intui; char *text; SHORT pens, left, top; {
  32.    intui->FrontPen = (pens >> 2) & 3;
  33.    intui->BackPen = pens & 3;
  34.    intui->DrawMode = JAM2;
  35.    intui->LeftEdge = left;
  36.    intui->TopEdge = top;
  37.    intui->ITextFont = NULL;
  38.    intui->NextText = NULL;
  39.    intui->IText = (UBYTE *)text;
  40.    }
  41.  
  42. /*
  43.  * Menu Creation
  44.  */
  45.  
  46. /* macro to compute size in bytes for menu with n items */
  47. #define MenuBytes(n)  (sizeof(struct Menu) + (n)*(sizeof(struct MenuItem) + sizeof(struct IntuiText)))
  48.  
  49. static struct Menu *menuList = NULL;
  50.  
  51. static AddMenu(title, size, names, init, rightify) int size, init, rightify; char *title, *names[]; {
  52.    struct Menu **menu;
  53.    struct MenuItem *items = NULL;
  54.    struct IntuiText *text = NULL;
  55.    int n, width = 0, itemLeft = 1, menuLeft = 5;
  56.    USHORT flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
  57.    if (init >= 0) {flags |= CHECKIT; itemLeft += CHECKWIDTH;}
  58.    for (menu = &menuList; *menu; menu = &((*menu)->NextMenu)) menuLeft += 90;
  59.    /* menu now points to where the next menu pointer should go */
  60.    *menu = (struct Menu *)AllocMem(MenuBytes(size), MEMF_CHIP);
  61.    if (*menu == NULL) return(TRUE); /* out of memory */
  62.    items = (struct MenuItem *)(sizeof(**menu) + (UBYTE *)*menu);
  63.    text = (struct IntuiText *)(size*sizeof(*items) + (UBYTE *)items);
  64.    InitText(text, (*menu)->MenuName = title, 0, 0, 0); /* just to measure it */
  65.    (*menu)->Width = 8 + IntuiTextLength(text);
  66.    for (n=0; n<size; n++) {
  67.       int thisWidth;
  68.       InitText(text, *names++, FORE0|BACK1, itemLeft, 1);
  69.       thisWidth = IntuiTextLength(text++);
  70.       width = max(width, thisWidth); /* max is macro; mustn't do ++ twice! */
  71.       }
  72.    text -= size;
  73.    width += 2;
  74.    if (init >= 0) width += CHECKWIDTH;
  75.    (*menu)->LeftEdge = rightify ? 630-width : menuLeft;
  76.    (*menu)->FirstItem = items;
  77.    (*menu)->NextMenu = NULL;
  78.    (*menu)->TopEdge = 0;
  79.    (*menu)->Height = 10;
  80.    (*menu)->Flags = MENUENABLED;
  81.    for (n=0; n<size; n++) {
  82.       items->NextItem = items+1;
  83.       items->LeftEdge = 0;
  84.       items->TopEdge = 11 * n;
  85.       items->Width = width;
  86.       items->Height = 10;
  87.       items->Flags = flags;
  88.       items->MutualExclude = (~(1 << n));
  89.       items->ItemFill = (APTR)text++;
  90.       items->SelectFill = NULL;
  91.       items->Command = 0;
  92.       items->SubItem = NULL;
  93.       items->NextSelect = 0;
  94.       items++;
  95.       }
  96.    (--items)->NextItem = NULL;
  97.    items -= (size-1);
  98.    if (init >= 0 && init < size) items[init].Flags |= CHECKED;
  99.    return(FALSE); /* no problems */
  100.    } /* end of AddMenu */
  101.  
  102. /* Specific menus */
  103.  
  104. static char *fileStrings[] = {"Start Capture", "Start Send", "End Capture", "Cancel Send"};
  105. static char *baudStrings[] = {" 300", "1200", "2400", "4800", "9600"};
  106. static char *dpyStrings[] = {"Vanilla", "SAIL"};
  107. static char *beepStrings[] = {"Brash", "Clear", "Calm", "Eerie", "Subdued", "Silent"};
  108. static char *wnStrings[] = {"Move to Back", "Move to Front", "Close Window"};
  109.  
  110. static InitMenus() { /* returns TRUE if unable to create them all */
  111.    return(AddMenu("File", 2, fileStrings, -1, FALSE)
  112.       || AddMenu("Baud", 5, baudStrings, 1, FALSE)
  113.       || AddMenu("Display", 2, dpyStrings, 1, FALSE)
  114.       || AddMenu("Beep", 6, beepStrings, 1, FALSE)
  115.       || AddMenu("Window", 3, wnStrings, -1, TRUE));
  116.    }
  117.  
  118. /*
  119.  * SAIL Font (weird chars in positions 0x80-0x9F)
  120.  */
  121.  
  122. static struct TextFont *tf;
  123.  
  124. static InitSAILFont(window) struct Window *window; {
  125.    struct TextAttr ta;
  126.    ta.ta_Name = "SAIL.font";
  127.    ta.ta_YSize = 8;
  128.    ta.ta_Style = 0;
  129.    ta.ta_Flags = FPF_ROMFONT | FPF_DISKFONT |
  130.       FPF_PROPORTIONAL | FPF_DESIGNED;
  131.    tf = (struct TextFont *)OpenDiskFont(&ta);
  132.    if (tf) SetFont(window->RPort, tf);
  133.    }
  134.  
  135. InitWindowStuff(window) struct Window *window; {
  136.    if (InitMenus() || MakeRequester()) {FreeMenus(); return(TRUE);}
  137.    InitSAILFont(window);
  138.    SetMenuStrip(window, menuList);
  139.    return(FALSE); /* no problem */
  140.    }
  141.  
  142. CleanUpWindow(window) struct Window *window; {
  143.    if (tf) CloseFont(tf);
  144.    if (window) ClearMenuStrip(window);
  145.    FreeMenus();
  146.    }
  147.  
  148. static FreeMenus() {
  149.    struct MenuItem *item;
  150.    while (menuList) {
  151.       int size = 0;
  152.       struct Menu *next = menuList->NextMenu;
  153.       for (item = menuList->FirstItem; item; item = item->NextItem) size++;
  154.       FreeMem(menuList, MenuBytes(size));
  155.       menuList = next;
  156.       }
  157.    }
  158.  
  159. /*
  160.  * Function to handle file menu commands, usually via a requester
  161.  */
  162.  
  163. FileMenu(w, item, r, s, flags) struct Window *w; int item, *flags; FILE **r, **s; {
  164.    /* called with item<0 to fix up menu item text to match current state */
  165.    switch (item) {
  166.       case 0: /* capture */
  167.          if (OpenOrCloseFile(w, r, "Capture to", "w", "Include control chars?")) *flags |= 1;
  168.         else *flags &= ~1;
  169.          break;
  170.       case 1: /* send */
  171.          if (OpenOrCloseFile(w, s, "Send", "r", "Convert LFs to CRs?")) *flags |= 2;
  172.          else *flags &= ~2;
  173.          break;
  174.       }
  175.    ((struct IntuiText *)menuList->FirstItem->ItemFill)->IText =
  176.       (UBYTE *)fileStrings[*r == NULL ? 0 : 2];
  177.    ((struct IntuiText *)menuList->FirstItem->NextItem->ItemFill)->IText =
  178.       (UBYTE *)fileStrings[*s == NULL ? 1 : 3];
  179.    }
  180.  
  181. /* The Requester */
  182.  
  183. static struct Requester myreq;
  184.  
  185. #define FNAMEBUFSIZE 60
  186. static UBYTE fnamebuf[FNAMEBUFSIZE];
  187.  
  188. static struct StringInfo fname = {
  189.    fnamebuf, NULL, 0, FNAMEBUFSIZE, 0, 0, 0, 0, 0, 0, 0, 0, NULL};
  190.  
  191. /* border for requester */
  192. #define FILREQWIDTH  400
  193. #define FILREQHEIGHT 130
  194. #define TEXTGAP      14
  195. #define TEXTTOP      10+TEXTGAP*2
  196.  
  197. static SHORT reqPairs[] = {
  198.    4, 2,                             FILREQWIDTH-5, 2,
  199.    FILREQWIDTH-5, FILREQHEIGHT-3,    4, FILREQHEIGHT-3,
  200.    4, 2,                             5, 2,
  201.    5, FILREQHEIGHT-3,                FILREQWIDTH-6, FILREQHEIGHT-3,
  202.    FILREQWIDTH-6, 2 };
  203.  
  204. static SHORT textPairs[] = {0, TEXTTOP-TEXTGAP-1, 0, TEXTTOP-TEXTGAP-1};
  205. static SHORT errorPairs[] = {0, TEXTTOP-2*TEXTGAP-1, 0, TEXTTOP-2*TEXTGAP-1};
  206.  
  207. /* border for activation gadgets */
  208. #define OCTLAP      2
  209. #define OCTWIDTH  100 /* tentative, adjusted based on font width */
  210. #define OCTHEIGHT  27 /* likewise adjusted based on font height */
  211. static SHORT gadPairs[] = {
  212.    OCTLAP*4, -OCTLAP,
  213.    OCTWIDTH-OCTLAP*4-1, -OCTLAP,
  214.    OCTWIDTH+OCTLAP*2-1, OCTLAP*2,
  215.    OCTWIDTH+OCTLAP*2-1, OCTHEIGHT-OCTLAP*2-1,
  216.    OCTWIDTH+OCTLAP*2-2, OCTLAP*2,
  217.    OCTWIDTH+OCTLAP*2-2, OCTHEIGHT-OCTLAP*2-1,
  218.    OCTWIDTH+OCTLAP*2-1, OCTHEIGHT-OCTLAP*2-1, 
  219.    OCTWIDTH-OCTLAP*4-1, OCTHEIGHT+OCTLAP-1,
  220.    OCTLAP*4, OCTHEIGHT+OCTLAP-1,
  221.    -OCTLAP*2, OCTHEIGHT-OCTLAP*2-1,
  222.    -OCTLAP*2, OCTLAP*2,
  223.    -OCTLAP*2+1, OCTHEIGHT-OCTLAP*2-1,
  224.    -OCTLAP*2+1, OCTLAP*2,
  225.    -OCTLAP*2, OCTLAP*2,
  226.    OCTLAP*4, -OCTLAP };
  227.  
  228. /* border and background for yes/no gadget */
  229. static SHORT ynBkgPairs[48];
  230. static SHORT ynBrdPairs[] = {-2,-1, -2,3, 1,3, 1,-1, -1,-1, -1,3, 0,3, 0,-1};
  231.  
  232. static struct Border reqBorder = {0, 0, 3, 0, JAM1, 9, reqPairs, NULL};
  233. static struct Border textBorder = {0, 0, 3, 2, JAM1, 2, textPairs, &reqBorder};
  234. static struct Border errBorder = {0, 0, 1, 2, JAM1, 2, errorPairs, &textBorder};
  235.  
  236. static struct Border gadBorder = {0, 0, 3, 2, JAM1, 15, gadPairs, NULL};
  237.  
  238. static struct Border ynBorder = {0, 0, 1, 0, JAM1, 8, ynBrdPairs, NULL};
  239. static struct Border ynBackground = {0, 0, 0, 2, JAM1, 24, ynBkgPairs, &ynBorder};
  240.  
  241. static struct IntuiText gadText[4], ynText[2];
  242. static struct IntuiText reqText, errorText, optText;
  243. static char reqTextChars[30];
  244.  
  245. static struct Gadget gadgets[5] = {
  246.   {&gadgets[1], 20,-20-OCTHEIGHT,OCTWIDTH,OCTHEIGHT,
  247.    GADGHCOMP | GRELBOTTOM, RELVERIFY | ENDGADGET, REQGADGET | BOOLGADGET,
  248.    (APTR)&gadBorder, NULL, &gadText[0], NULL, NULL, TRUE, NULL},
  249.   {&gadgets[2], -20-OCTWIDTH,-20-OCTHEIGHT,OCTWIDTH,OCTHEIGHT,
  250.    GADGHCOMP | GRELRIGHT | GRELBOTTOM, RELVERIFY | ENDGADGET, REQGADGET | BOOLGADGET,
  251.    (APTR)&gadBorder, NULL, &gadText[1], NULL, NULL, FALSE, NULL},
  252.   {&gadgets[3], 0,TEXTTOP+TEXTGAP*3/2,0,0,
  253.    GADGHCOMP, RELVERIFY, REQGADGET | BOOLGADGET,
  254.    (APTR)&ynBackground, NULL, &ynText[0], NULL, NULL, TRUE, (APTR)&gadgets[3]},
  255.   {&gadgets[4], 0,TEXTTOP+TEXTGAP*3/2,0,0,
  256.    GADGHCOMP, RELVERIFY, REQGADGET | BOOLGADGET,
  257.    (APTR)&ynBackground, NULL, &ynText[1], NULL, NULL, FALSE, (APTR)&gadgets[2]},
  258.   {NULL, FILREQWIDTH/5,TEXTTOP,FILREQWIDTH*3/5,12,
  259.    GADGHCOMP, STRINGCENTER, REQGADGET | STRGADGET,
  260.    NULL, NULL, NULL, NULL, (APTR)&fname, NULL, NULL} };
  261.  
  262. static MakeRequester() {
  263.    int n, width;
  264.    BYTE height;
  265.    SHORT *coord;
  266.    InitRequester(&myreq);
  267.    myreq.LeftEdge = (640-FILREQWIDTH)/2;
  268.    myreq.TopEdge = 8;
  269.    myreq.Width = FILREQWIDTH;
  270.    myreq.Height = FILREQHEIGHT;
  271.    myreq.ReqGadget = gadgets;
  272.    myreq.ReqBorder = &textBorder;
  273.    myreq.ReqText = &reqText;
  274.    myreq.BackFill = 2;
  275.    GetPrefs(&height, 1); /* get height of default font */
  276.    InitText(&ynText[0], "Yes", FORE1|BACK0, 4, 2);
  277.    InitText(&ynText[1], "No", FORE1|BACK0, 4, 2);
  278.    width = IntuiTextLength(&ynText[0]);
  279.    ynText[1].LeftEdge += (width-IntuiTextLength(&ynText[1])) / 2;
  280.    gadgets[2].Width = gadgets[3].Width = width += 8;
  281.    gadgets[2].Height = gadgets[3].Height = height+3;
  282.    coord = ynBkgPairs;
  283.    for (n=0; n<height+3; n++) {
  284.       *coord++ = n&1 ? width-1 : 0;
  285.       *coord++ = n;
  286.       *coord++ = n&1 ? 0 : (width-1);
  287.       *coord++ = n;
  288.       }
  289.    ynBackground.Count = (height+3)*2; /* number of pairs to draw background */
  290.    coord = ynBrdPairs-1;
  291.    for (n=0; n<ynBorder.Count; n++) {
  292.       if (*++coord >= 0) *coord += width;
  293.       if (*++coord >= 0) *coord += height;
  294.       }
  295.    InitText(&gadText[0], "  CONFIRM  ", FORE0|BACK1, 2, height+1);
  296.    InitText(&gadText[1], " FORGET IT ", FORE0|BACK1, 2, height+1);
  297.    InitText(&gadText[2], "           ", FORE0|BACK1, 2, 1);
  298.    InitText(&gadText[3], "           ", FORE0|BACK1, 2, height*2+1);
  299.    gadText[0].NextText = gadText[1].NextText = &gadText[2];
  300.    gadText[2].NextText = &gadText[3];
  301.    gadgets[1].Width = gadgets[0].Width = width = IntuiTextLength(gadText) + 4;
  302.    gadgets[1].Height = gadgets[0].Height = height = height*3 + 2;
  303.    gadgets[1].LeftEdge = -20-width;
  304.    coord = gadPairs-1;
  305.    for (n=0; n<gadBorder.Count; n++) {
  306.       if (*++coord > OCTWIDTH/2) *coord += width-OCTWIDTH;
  307.       if (*++coord > OCTHEIGHT/2) *coord += height-OCTHEIGHT;
  308.       }
  309.    InitText(&reqText, reqTextChars, FORE2|BACK3, 0, TEXTTOP - TEXTGAP);
  310.    reqText.NextText = &optText;
  311.    InitText(&optText, NULL, FORE1|BACK2, 0, gadgets[2].TopEdge + ynText[0].TopEdge);
  312.    InitText(&errorText, " Can't open file; try again ", FORE0|BACK1, 0, TEXTTOP - 2*TEXTGAP);
  313.    errorText.NextText = &reqText;
  314.    width = IntuiTextLength(&errorText);
  315.    errorPairs[0] = errorText.LeftEdge = (FILREQWIDTH-width) / 2;
  316.    errorPairs[2] = errorPairs[0] + width - 1;
  317.    return(FALSE); /* no problems */
  318.    }
  319.  
  320. static OpenOrCloseFile(w, file, label, mode, option) struct Window *w; FILE **file; char *label, *mode, *option; {
  321.    struct IntuiMessage *message;
  322.    ULONG class;
  323.    struct Gadget *gadg;
  324.    int proceed, k, opt;
  325.    if (*file != NULL) {fclose(*file); *file = NULL; return(NULL);}
  326.    sprintf(reqTextChars, " %s file: ", label);
  327.    k = IntuiTextLength(&reqText);
  328.    textPairs[0] = reqText.LeftEdge = (FILREQWIDTH-k) / 2;
  329.    textPairs[2] = textPairs[0] + k - 1;
  330.    optText.IText = (UBYTE *)option;
  331.    k = IntuiTextLength(&optText);
  332.    opt = gadgets[2].Width + 2; /* distance between Yes gadget and No gadget */
  333.    optText.LeftEdge = (FILREQWIDTH - (k + 3*opt)) / 2;
  334.    gadgets[2].LeftEdge = optText.LeftEdge + k + opt;
  335.    gadgets[3].LeftEdge = gadgets[2].LeftEdge + opt;
  336.    fnamebuf[0] = k = 0;
  337.    myreq.ReqBorder = &textBorder;
  338.    myreq.ReqText = &reqText;
  339.    gadgets[2].Flags &= ~SELECTED;
  340.    gadgets[3].Flags |= SELECTED;
  341.    gadgets[2].Activation |= TOGGLESELECT;
  342.    gadgets[3].Activation &= ~TOGGLESELECT;
  343.    for (;;) {
  344.       if (! Request(&myreq, w)) return(NULL); /* couldn't open requester */
  345.       for (proceed=TRUE; proceed; ) {
  346.          while (message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
  347.             class = message->Class;
  348.             gadg = (struct Gadget *)message->IAddress;
  349.             ReplyMsg(message);
  350.             switch (class) {
  351.                case GADGETUP:
  352.                   if (gadg->Activation & ENDGADGET) {
  353.                      k = gadg->GadgetID;
  354.                      opt = gadgets[2].Flags & SELECTED;
  355.                      }
  356.                   else if (gadg->Activation & TOGGLESELECT) {
  357.                      gadg->Activation &= ~TOGGLESELECT;
  358.                      gadg = (struct Gadget *)gadg->UserData;
  359.                      gadg->Flags &= ~SELECTED;
  360.                      gadg->Activation |= TOGGLESELECT;
  361.                      RefreshGadgets(&gadgets[2], w, &myreq);
  362.                      }
  363.                   break;
  364.                case REQCLEAR: proceed = FALSE; break;
  365.                }
  366.             }
  367.          }
  368.       /* requester came down, now check what we're supposed to do */
  369.       if (!k) return(NULL); /* user said to forget it */
  370.       if (*file = fopen(fnamebuf, mode)) return(opt); /* no problem */
  371.       /* bring requester back, this time with error message added */
  372.       myreq.ReqBorder = &errBorder;
  373.       myreq.ReqText = &errorText;
  374.       }
  375.    }
  376.